package es.udc.acs.banco.server;


import es.udc.acs.banco.sesion.ControlSesion;
import es.udc.acs.banco.sesion.Sesion;
import es.udc.acs.banco.util.GestorProperties;
import es.udc.acs.parser.ParserMensaje;
import es.udc.acs.udp.QuestionServer;
import es.udc.acs.utils.CodigosFAP;


public class BancoServer implements QuestionServer {
	
	@Override
	public String procesarPregunta(String mensaje) {		
		
		GestorProperties.tratarMensaje("BancoServer:mensaje recibido: ",mensaje);

		String origen  = ParserMensaje.obtenerOrigen(mensaje);
		String destino = ParserMensaje.obtenerDestino(mensaje);
		String tipo    = ParserMensaje.obtenerTipo(mensaje);
		String res;
		
		// comprobacion del destino y origen
		if (!destino.equals(GestorProperties.
						devolverPropiedad(GestorProperties.IDBANCO)) 
			|| !origen.equals(GestorProperties.
						devolverPropiedad(GestorProperties.IDCONSORCIO))) {
			res = CodigosFAP.CE_OTRAS_CAUSAS;	
			System.out.println("BancoServer:origen y destino erroneos");
		}
		if (CodigosFAP.esControl(tipo)) {
			res = preguntaControl(tipo);		
		} else if (CodigosFAP.esDatos(tipo)) {
			res = preguntaDatos(tipo, mensaje);
		} else {
			res = CodigosFAP.CE_OTRAS_CAUSAS;	
			System.out.println("BancoServer:No se que mensaje es");
		}
		
		try {
			if (ControlSesion.obtenerSesion().isModoVisualizar())
				System.out.println("BancoServer:mensaje enviado: "+destino+origen+res);
		} catch (Exception e) {}		
		
		
		GestorProperties.tratarMensaje("BancoServer:mensaje enviado: ",destino+origen+res);

		return destino+origen+res;		
	}
	
	
	private String preguntaControl(String tipo) {
		
		String tipoR;
		String codRes;
		String codError;
		
		ControlServer cs = new ControlServer();
		tipoR = CodigosFAP.obtenerTipoRespuesta(tipo);
		
		// si el mensaje no tiene un tipo correcto
		if (tipoR == null) {
			return CodigosFAP.CE_OTRAS_CAUSAS;
		}
		
		try {				
			Sesion sesion = ControlSesion.obtenerSesion();
			String codigo = sesion.procesarRControl(tipo);

			// si el estado nos permite la operacion
			if (codigo.equals(CodigosFAP.CE_CORRECTO)) {
				
				String res = cs.procesarPregunta(tipo);	
				
				if (res.equals(CodigosFAP.CE_CORRECTO)) {
					codRes = CodigosFAP.CODRE_CORRECTA;	
				} else { 				
					codRes = CodigosFAP.CODRE_DENEGADA;
				}
				
				codError = res;
			}
			else {
				codRes = CodigosFAP.CODRE_DENEGADA;
				codError = codigo;
			}
			
		} catch (Exception e) {
			codRes = CodigosFAP.CODRE_DENEGADA;
			codError = CodigosFAP.CE_OTRAS_CAUSAS;
		}			

		return tipoR+codRes+codError;		
	}
	
	
	private String preguntaDatos(String tipo,String mensaje) {
		
		String tipoR;
		String res;
		String subcabecera = ParserMensaje.obtenerSubcabecera(mensaje);
		
		DatosServer ds = new DatosServer();
		tipoR = CodigosFAP.obtenerTipoRespuesta(tipo);
		
		// si el mensaje no tiene el tipo correcto 
		if (tipoR == null) 
			return CodigosFAP.CE_OTRAS_CAUSAS;
		
		try {				
			Sesion sesion = ControlSesion.obtenerSesion();
			String codigo = sesion.procesarRDatos(subcabecera);

			// estamos forzando la recupearcion por un canal
			if (codigo.equals(CodigosFAP.NO_RESPUESTA))
				return codigo;
			
			// modo recuperacion -> respuesta contestada se reenvia
			if (codigo.equals(CodigosFAP.RE_RESPUESTA)) {
				res = sesion.obtenerRespuesta(subcabecera);
			} else {			
				
				if (codigo.equals(CodigosFAP.CE_CORRECTO)) {			
					res = ds.procesarPregunta(mensaje, tipo); 
				} else {// el codigo de error correspondiente
					res = codigo;
				}
				
				aumentarMarcadores(sesion, res, tipo);
				
				// guardamos la ultima respuesta en el canal
				sesion.guardarRespuesta(subcabecera, res);
			}
			
		} catch (Exception e) {
			res = CodigosFAP.CE_OTRAS_CAUSAS;
		}			
		
		return tipoR+subcabecera+res;		
	}
	
	
	private void aumentarMarcadores(Sesion sesion,String res,String tipo) {
		try {
			// para llevar la cuenta del numero de operaciones
			if (res.substring(0, 2).
					equals(CodigosFAP.CR_CONSULTA_ACEPTADA)) {

				if (tipo.equals(CodigosFAP.CM_C_PD_REINTEGRO)) {
					sesion.sumarReintegro();
				} else if (tipo.equals(CodigosFAP.CM_C_PD_ABONO)) {					
					sesion.sumarAbono();
				} else if (tipo.equals(CodigosFAP.CM_C_PD_TRASPASO)) {
					sesion.sumarTraspaso();		
				}
			}	
		} catch(Exception e) {}
	}
}
